#ifndef _PLIST_TEMPLATE_   /* если не обращена макро const включается код  */
#define _PLIST_TEMPLATE_

/* класс исключений */
class PQueueException {
	const char *msg;
public:
	PQueueException(const char *m): msg(m)
	{ }
	~PQueueException() { }

	const char * GetMsg() const { return msg; }
};

template <typename Tp> class PQueue; /* объявление шаблона класса */

/* внутри очередь организована как односвязный список */

/* класс объектов односвязного списка */
template <typename Tp>
class ListNode {
	friend class PQueue<Tp>;

	int prior;
	Tp data;
	ListNode *next;

	ListNode(int pr, const Tp& dt, ListNode *n):
		prior(pr), data(dt), next(n)
	{ }
};

/* определение шаблона класса */
template <typename Tp>
class PQueue {
	ListNode<Tp> *head;
public:
	PQueue(): head(0) { } /* определение конструктора */
	
	bool isempty() const { return head == 0; }  /* определение функции, пуста очередь или нет */

	void Put(const int prior, const Tp& data); /* int - передаёт значение , int& - ссылка на переменную */
	void Get(int& prior, Tp& data);

	~PQueue(); /* диструктор - удаляет все оставшиеся элементы */
};

/* определение методов */
template <typename Tp>
void PQueue<Tp>::Put(const int prior, const Tp& data) /* добавление элементов в очередь */
{
	ListNode<Tp> *curr, *prev; /* curr - текущий, prev - предыдущий */

	for (curr = head, prev = 0;/* должно стоять условие,пустой блок - бесконечность!*/; prev = curr, curr = curr->next) 
		if ((curr == 0) || (prior < curr->prior)) {
			ListNode<Tp> *elem = 
				new ListNode<Tp>(prior, data, curr);
			
			if (prev == 0) 
				head = elem;
			else
				prev->next = elem;

			break; 
		};
}

template <typename Tp>
void PQueue<Tp>::Get(int& prior, Tp& data) /* взятие данных из очереди */
{
	if (head == 0)
		throw PQueueException("List is empty"); /* throw - сгенерировать ислючение */

	ListNode<Tp> *del = head;
	head = head->next;

	prior = del->prior;
	data = del->data;

	delete del; /* очистка памяти */
}

template <typename Tp>
PQueue<Tp>::~PQueue()  /* диструктор */
{
	ListNode<Tp> *del;

	while (head) {
		del = head;
		head = head->next;
		delete del;
	}
}
/* конец =) */

#endif 
